unit Settings;

interface

uses
  Classes, Graphics, IniFiles;

type
  TSettings = class(TPersistent)
  private
    FModified: Boolean;
    FFileMaxCount: Integer;
    FFileMaxWidth: Integer;
    FViewFont: TFont;
    FTabSize: Integer;
    FTabText: string;
    procedure ObjectChanged(Sender: TObject);
    procedure SetFileMaxCount(const Value: Integer);
    procedure SetFileMaxWidth(const Value: Integer);
    procedure SetViewFont(const Value: TFont);
    procedure SetTabSize(const Value: Integer);
  protected
    procedure AssignTo(Dest: TPersistent); override;
    procedure Changed; virtual;
  public
    constructor Create;
    destructor Destroy; override;

    procedure SaveToFile(const AFileName: string); overload;
    procedure LoadFromFile(const AFileName: string); overload;
    procedure SaveToFile(AIni: TIniFile); overload;
    procedure LoadFromFile(AIni: TIniFile); overload;

    property Modified: Boolean read FModified write FModified;
    property FileMaxWidth: Integer read FFileMaxWidth write SetFileMaxWidth;
    property FileMaxCount: Integer read FFileMaxCount write SetFileMaxCount;
    property ViewFont: TFont read FViewFont write SetViewFont;
    property TabSize: Integer read FTabSize write SetTabSize;
    property TabText: string read FTabText;
  end;

var
  AppSettings: TSettings;

implementation

uses
  Helpers,
  SysUtils, StrUtils;

const
  DefaultSection = 'Settings';
  DefaultFileMaxCount = 10;
  DefaultFileMaxWidth = 50;
  DefaultFontName = 'Consolas';
  DefaultFontSize = 11;
  DefaultTabSize = 2;

{ TSettings }

constructor TSettings.Create;
begin
  inherited;
  FFileMaxCount := DefaultFileMaxCount;
  FFileMaxWidth := DefaultFileMaxWidth;
  FViewFont := TFont.Create;
  FViewFont.Name := DefaultFontName;
  FViewFont.Size := DefaultFontSize;
  FViewFont.OnChange := ObjectChanged;
  SetTabSize(DefaultTabSize);
  FModified := False;
end;

destructor TSettings.Destroy;
begin
  FViewFont.Free;
  inherited;
end;

procedure TSettings.AssignTo(Dest: TPersistent);
begin
  if Dest is TSettings then
    with TSettings(Dest) do
    begin
      FViewFont.Assign(Self.FViewFont);
      FModified := Self.FModified;
    end
  else
    inherited;
end;

procedure TSettings.Changed;
begin
  FModified := True;
end;

procedure TSettings.ObjectChanged(Sender: TObject);
begin
  Changed;
end;

procedure TSettings.SaveToFile(const AFileName: string);
begin
  var Ini := TIniFile.Create(AFileName);
  try
    SaveToFile(Ini);
  finally
    Ini.Free;
  end;
end;

procedure TSettings.LoadFromFile(const AFileName: string);
begin
  var Ini := TIniFile.Create(AFileName);
  try
    LoadFromFile(Ini);
  finally
    Ini.Free;
  end;
end;

procedure TSettings.LoadFromFile(AIni: TIniFile);
begin
  FFileMaxCount := AIni.ReadInteger(DefaultSection, 'FileMaxCount', DefaultFileMaxCount);
  FFileMaxWidth := AIni.ReadInteger(DefaultSection, 'FileMaxWidth', DefaultFileMaxWidth);
  FViewFont.Name := AIni.ReadString(DefaultSection, 'ViewFont.Name', DefaultFontName);
  FViewFont.Size := AIni.ReadInteger(DefaultSection, 'ViewFont.Size', DefaultFontSize);
  SetTabSize(AIni.ReadInteger(DefaultSection, 'TabSize', DefaultTabSize));
end;

procedure TSettings.SaveToFile(AIni: TIniFile);
begin
  AIni.WriteInteger(DefaultSection, 'FileMaxCount', FFileMaxCount);
  AIni.WriteInteger(DefaultSection, 'FileMaxWidth', FFileMaxWidth);
  AIni.WriteString(DefaultSection, 'ViewFont.Name', FViewFont.Name);
  AIni.WriteInteger(DefaultSection, 'ViewFont.Size', FViewFont.Size);
  AIni.WriteInteger(DefaultSection, 'TabSize', FTabSize);
end;

procedure TSettings.SetFileMaxCount(const Value: Integer);
begin
  if (FFileMaxCount <> Value) and (Value > 0) then
  begin
    FFileMaxCount := Value;
    Changed;
  end;
end;

procedure TSettings.SetFileMaxWidth(const Value: Integer);
begin
  if (FFileMaxWidth <> Value) and (Value > 0) then
  begin
    FFileMaxWidth := Value;
    Changed;
  end;
end;

procedure TSettings.SetViewFont(const Value: TFont);
begin
  FViewFont.Assign(Value);
end;

procedure TSettings.SetTabSize(const Value: Integer);
begin
  if (FTabSize <> Value) and (Value >= 0) then
  begin
    FTabSize := Value;
    FTabText := DupeString(' ', Value);
    Changed;
  end;
end;

initialization
  AppSettings := TSettings.Create;
finalization
  AppSettings.Free;
end.
